using System;
using System.Collections.Generic;
using System.Text;

using Deepcode.Flux.Core.Systems.CMS;

namespace Deepcode.Flux.Core.UI.CMS
{
	/// <summary>
	/// Base class for all content forms
	/// </summary>
	public abstract class CMSContentForm : Deepcode.Flux.Core.UI.AdministrationModulePage
	{
		#region Permission Code Override
		public override string RequiredPermissionCode { get { return "FluxCMSAccess"; } }
		#endregion
		#region ViewState and Properties
		/// <summary>
		/// Store the ID of the parent passed in to the action
		/// </summary>
		protected int ParentID
		{
			get
			{
				object o = ViewState["PID"];
				if (o == null) return -1;
				return (int)o;
			}
			set
			{
				ViewState["PID"] = value;
			}
		}
		/// <summary>
		/// Store the ID of the content passed to the actions
		/// </summary>
		protected int ContentID
		{
			get
			{
				object o = ViewState["CID"];
				if (o == null) return -1;
				return (int)o;
			}
			set
			{
				ViewState["CID"] = value;
			}
		}
		#endregion
		#region Page Load Event
		protected void Page_Load(object sender, EventArgs e)
		{
			if (!Page.IsPostBack)
			{
				// Load path data
				ContentID = GetAttribute("ContentID", -1);
				ParentID = GetAttribute("ParentID", -1);
			}

			SetupForm( ContentID, ParentID );

			if(!Page.IsPostBack)
			{
				// If we've been passed content to edit, edit it
				if (ContentID != -1)
				{
					ContentManager c = new ContentManager(true);
					ContentObject o = c.AdxGetByID(ContentID);
					if (o == null) ContentID = -1;
					else
						LoadContent(o);
				}
			}
		}
		#endregion
		#region Utility Methods
		/// <summary>
		/// Utility function to ask the content and content tree frames to refresh
		/// </summary>
		protected virtual void GoBack(bool reload)
		{
			// Revert back to content listing, reselect last selected if possible
			int iid = ContentID;
			if (iid == -1) iid = ParentID;
			
			string url = String.Format(
				"~/admin/private/cms/main/content.aspx?selectID={0}{1}",
				iid,
				reload ? "&reload=true" : "" 
				);
			
			Response.Redirect(url, true);
		}
		#endregion
		#region Button Handlers
		/// <summary>
		/// Hook this up to the standard save button, it will in turn
		/// create or load the existing content, perform any checks to 
		/// ensure the user is the owner etc and then invoke the SaveContent
		/// override to populate data.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void btnSave_Click(object sender, EventArgs e)
		{
			if (!Page.IsValid) return;

			ContentManager cms = new ContentManager(true);

			if (ContentID == -1)
			{
				// Creating a new record
				ContentObject co = new ContentObject(FormTypeCode, ParentID, CurrentUser.PK_ID);
				SaveContent(ref co);
				cms.Save(co, CurrentUser.PK_ID);

				// Audit
				Deepcode.Flux.Core.Systems.Audit.Quick.QuickAudit.RaiseInformation(new Deepcode.Flux.Core.Systems.Audit.Quick.AuditUser(),
					"Flux",
					"Content Manager",
					"created content {0}", co.NodeTitle);
			}
			else
			{
				// Modification of an existing record
				ContentObject co = cms.AdxGetByID(ContentID);
				if (co == null) GoBack(false);
				if (co.WorkflowStatus != ContentObjectStatus.CHECKEDOUT) GoBack(false);
				if (co.FK_CheckedOutTo != CurrentUser.PK_ID) GoBack(false);
				SaveContent( ref co );
				cms.Save(co, CurrentUser.PK_ID);

				// Audit
				Deepcode.Flux.Core.Systems.Audit.Quick.QuickAudit.RaiseInformation(new Deepcode.Flux.Core.Systems.Audit.Quick.AuditUser(),
					"Flux",
					"Content Manager",
					"modified content {0}", co.NodeTitle);

			}
			GoBack(true);
		}
		/// <summary>
		/// Hook this up to the cancel button to return to the content list
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void btnCancel_Click(object sender, EventArgs e)
		{
			GoBack(false);
		}
		#endregion
		#region Virtual methods and properties
		/// <summary>
		/// MUST override this property to specify the type id of the
		/// content type being managed by the form
		/// </summary>
		protected abstract string FormTypeCode { get; }

		/// <summary>
		/// Override and implement this method to populate
		/// the form from the content object specified
		/// </summary>
		/// <param name="load"></param>
		protected virtual void LoadContent(ContentObject load)
		{
		}
		/// <summary>
		/// Override and implement this method to populate
		/// the content object specified with the field
		/// values from the form.
		/// </summary>
		/// <param name="save"></param>
		protected virtual void SaveContent(ref ContentObject save)
		{
		}
		/// <summary>
		/// Override and implement this method to setup anything on the
		/// form regardless of whether or not it is editing or adding 
		/// a record to the datastore. It is called during page load,
		/// but before the record itself is loaded.
		/// </summary>
		protected virtual void SetupForm(int ContentID, int ParentID)
		{
		}
		#endregion
	}
}
